package com.mgg.payment.controller.weixin;

import com.mgg.common.dto.OrderDTO;
import com.mgg.common.enums.OrderPayWayEnum;
import com.mgg.common.enums.OrderStatusEnum;
import com.mgg.common.exception.ServiceException;
import com.mgg.common.util.JsonUtils;
import com.mgg.common.util.ResultVOUtil;
import com.mgg.payment.config.WxPayAccountConfig;
import com.mgg.payment.enums.PaymentResultEnum;
import com.mgg.payment.model.PayResponse;
import com.mgg.payment.model.wxpay.WxPayResponse;
import com.mgg.payment.service.order.SalesOrderService;
import com.mgg.payment.service.pay.PaymentService;
import com.mgg.payment.service.weixin.WxPayService;
import com.mgg.payment.util.MathUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

@Controller
@RequestMapping("/weixin")
public class WeixinPayController {

	private Logger log = LoggerFactory.getLogger(getClass());

	@Autowired
    private SalesOrderService orderService;

	@Autowired
    private WxPayService wxPayService;
    
    @Autowired
    private PaymentService paymentService;
    
    @Autowired
	private WxPayAccountConfig wxPayAccountConfig;
    
	/**
	 * 发起支付
	 * @throws Exception 
	 */
	@GetMapping(value = "/create")
	@ResponseBody
	public Object pay(@RequestParam("orderId") String orderId) throws Exception {
		OrderDTO order = orderService.getOrderByOrderId(orderId);
		if (order == null) {
			return ResultVOUtil.error(PaymentResultEnum.ORDER_NOT_EXIST);
		}
		if(order.getStatus() != OrderStatusEnum.UN_PAY.getCode()) {
			return ResultVOUtil.error(PaymentResultEnum.ORDER_STATUS_ERROR);
		}
        
        //2. 发起支付
        WxPayResponse payResponse = wxPayService.create(order.getOrderId(), order.getOrderTotal());
        return ResultVOUtil.success(payResponse);
	}

	/**
	 * 异步回调
	 */
	@PostMapping(value = "/notify")
	public ModelAndView notify(@RequestBody String notifyData) throws Exception {
		//1. 验证签名
        //2. 支付的状态
        //3. 支付金额
        //4. 支付人(下单人 == 支付人)
		//微信支付
        PayResponse payResponse = wxPayService.notify(notifyData,wxPayAccountConfig.getMchKey());
    	log.info("【微信支付】异步通知, payResponse={}", JsonUtils.toJson(payResponse));
        String orderId = payResponse.getOrderId();

        //查询订单
		OrderDTO order = orderService.getOrderByOrderId(orderId);
        //判断订单是否存在
        if (order == null) {
            log.error("【微信支付】异步通知, 订单不存在, orderId={}", orderId);
            throw new ServiceException(PaymentResultEnum.ORDER_NOT_EXIST.getCode(),PaymentResultEnum.ORDER_NOT_EXIST.getMessage());
        }
		if(order.getStatus() != OrderStatusEnum.UN_PAY.getCode()) {
            log.error("【微信支付】异步通知, 订单状态异常, orderId={}", orderId);
			throw new ServiceException(PaymentResultEnum.ORDER_STATUS_ERROR.getCode(),PaymentResultEnum.ORDER_STATUS_ERROR.getMessage());
		}

        //判断金额是否一致(0.10   0.1)
        if (!MathUtils.equals(payResponse.getOrderAmount(), order.getOrderTotal().doubleValue())) {
            log.error("【微信支付】异步通知, 订单金额不一致, orderId={}, 微信通知金额={}, 系统金额={}",
                    payResponse.getOrderId(),
                    payResponse.getOrderAmount(),
                    order.getOrderTotal());
            throw new ServiceException(PaymentResultEnum.WXPAY_NOTIFY_MONEY_VERIFY_ERROR.getCode(),PaymentResultEnum.WXPAY_NOTIFY_MONEY_VERIFY_ERROR.getMessage());
        }
		
		paymentService.paySuccess(order, OrderPayWayEnum.WEIXIN.getCode(), payResponse.getOutTradeNo());
        return new ModelAndView("pay/success");
	}
	
	/**
	 * 微信H5异步回调
	 */
	@PostMapping(value = "/h5notify")
	public ModelAndView h5Notify(@RequestBody String notifyData) throws Exception {
		//微信支付
        PayResponse payResponse = wxPayService.notify(notifyData,"v0EyBtt737c08QaNniSJJQGjS9Ts9ewC");
    	log.info("【微信支付】异步通知, payResponse={}", JsonUtils.toJson(payResponse));
        String orderId = payResponse.getOrderId();

        //查询订单
        OrderDTO order = orderService.getOrderByOrderId(orderId);
        //判断订单是否存在
        if (order == null) {
            log.error("【微信支付】异步通知, 订单不存在, orderId={}", orderId);
            throw new ServiceException(PaymentResultEnum.ORDER_NOT_EXIST.getCode(),PaymentResultEnum.ORDER_NOT_EXIST.getMessage());
        }
        if(order.getStatus() != OrderStatusEnum.UN_PAY.getCode()) {
            log.error("【微信支付】异步通知, 订单状态异常, orderId={}", orderId);
            throw new ServiceException(PaymentResultEnum.ORDER_STATUS_ERROR.getCode(),PaymentResultEnum.ORDER_STATUS_ERROR.getMessage());
        }

        //判断金额是否一致(0.10   0.1)
        if (!MathUtils.equals(payResponse.getOrderAmount(), order.getOrderTotal().doubleValue())) {
            log.error("【微信支付】异步通知, 订单金额不一致, orderId={}, 微信通知金额={}, 系统金额={}",
                    payResponse.getOrderId(),
                    payResponse.getOrderAmount(),
                    order.getOrderTotal());
            throw new ServiceException(PaymentResultEnum.WXPAY_NOTIFY_MONEY_VERIFY_ERROR.getCode(),PaymentResultEnum.WXPAY_NOTIFY_MONEY_VERIFY_ERROR.getMessage());
        }
		
		paymentService.paySuccess(order, OrderPayWayEnum.WEIXIN.getCode(), payResponse.getOutTradeNo());
        return new ModelAndView("pay/success");
	}
	
	
	/**
	 * 微信H5手动异步回调
	 */
	@PostMapping(value = "/hnotify")
	public Object hNotify(@RequestParam String orderId, @RequestParam String tradeNo) throws Exception {
    	log.info("【微信支付】异步通知, orderId={}, tradeNo={}", orderId, tradeNo);
        //查询订单
        OrderDTO order = orderService.getOrderByOrderId(orderId);
        //判断订单是否存在
        if (order == null) {
            log.error("【微信支付】异步通知, 订单不存在, orderId={}", orderId);
            throw new ServiceException(PaymentResultEnum.ORDER_NOT_EXIST.getCode(),PaymentResultEnum.ORDER_NOT_EXIST.getMessage());
        }
        if(order.getStatus() != OrderStatusEnum.UN_PAY.getCode()) {
            log.error("【微信支付】异步通知, 订单状态异常, orderId={}", orderId);
            throw new ServiceException(PaymentResultEnum.ORDER_STATUS_ERROR.getCode(),PaymentResultEnum.ORDER_STATUS_ERROR.getMessage());
        }
		paymentService.paySuccess(order, OrderPayWayEnum.WEIXIN.getCode(), tradeNo);
        return ResultVOUtil.success();
	}
}
